﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace NGIS.Data.Schema
{
    public abstract  class UnitAbstract
    {
        private string id;
        public  string ID { get { return id; } set { id = value; } }

        private UnitType unitType;
        public UnitType UType { get { return unitType; }  set { unitType = value; } }

        private DimensionClass dimension;
        public DimensionClass Dimension { get { return dimension; } set { dimension = value; } }
        public List<LocalizationClass> Localizations { get { return Localizations; } }
        private List<LocalizationClass> localizations = new List<LocalizationClass>();

        public virtual void Add_Localization(LocalizationClass item) { return; }
        public virtual bool Remove_Localization(LocalizationClass item) { return false; }
        public virtual bool Remove_Localization(LocalizationEnum local) { return false; }
        public virtual LocalizationClass Return_Localization(LocalizationEnum local) { return null; }
    }

    /// <summary>
    /// 单位类别
    /// </summary>
    public enum UnitType
    {
        basic=1,//基础单位
        primtive=2,//拓展单位
        dervation=3//组合单位
    }
    
    /// <summary>
    /// 基本单位
    /// </summary>
    public class UnitBasic : UnitAbstract
    {
        #region 构造函数
        public UnitBasic()
        {
        }

        public UnitBasic(string unit_id,DimensionClass unit_dimension)
        {
            id = unit_id;
            dimension = unit_dimension;
        }
        #endregion
      
        private string id;
        public new string ID
        {
            get { return id; }
            set { id = value; }
        }

        private DimensionClass dimension;
        public new DimensionClass Dimension
        {
            get { return dimension; }
            set { dimension = value; }
        }

        private List<LocalizationClass> localizations=new List<LocalizationClass> ();
        public new  List<LocalizationClass> Localizations
        {
            get { return localizations; }
        }


        public override void Add_Localization(LocalizationClass local)
        {
            localizations.Add(local);
        }

        public override bool Remove_Localization(LocalizationClass item)
        {
           foreach(LocalizationClass temp in localizations)
           {
               if (temp == item)
                   return  localizations.Remove(temp);
              
           }
           return false;
        }

        public override bool Remove_Localization(LocalizationEnum local)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp.Local == local)
                    return localizations.Remove(temp);

            }
            return false;
        }

        public override LocalizationClass Return_Localization(LocalizationEnum local)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp.Local == local)
                    return temp;

            }
            return null;
        }
    }


    /// <summary>
    /// 拓展单位
    /// </summary>
    public class UnitPrimtive : UnitAbstract
    {
        #region 构造函数

        public UnitPrimtive()
        {
        }

        public UnitPrimtive(UnitBasic basic)
        {
            unitbasic = basic;
        }

        public UnitPrimtive(UnitBasic basic, string id, string dimension)
        {

        }

        #endregion

        private UnitBasic unitbasic;
        public UnitBasic UnitBasic
        {
            get { return unitbasic; }
            set { unitbasic = value; }
        }


        private string id;
        public new  string ID
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }

        private DimensionClass dimension;
        public new DimensionClass Dimension
        {
            get
            {
                return dimension;
            }
            set
            {
                dimension = value;
            }
        }

        private List<LocalizationClass> localizations = new List<LocalizationClass>();
        public new  List<LocalizationClass> Localizations
        {
            get { return localizations; }
        }

        public override void Add_Localization(LocalizationClass item)
        {
            if (item != null)
            {
                localizations.Add(item);
            }
        }

        public override bool Remove_Localization(LocalizationEnum item)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp.Local == item)
                    return localizations.Remove(temp);

            }
            return false;
        }

        public override bool Remove_Localization(LocalizationClass item)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp == item)
                    return localizations.Remove(temp);

            }
            return false;
        }

        public override LocalizationClass Return_Localization(LocalizationEnum local)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp.Local == local)
                    return temp;

            }
            return null;
        }

        private string expression;
        public string Expression
        {
            get { return expression; }
            set { expression = value; }
        }


    }

    /// <summary>
    /// 组合单位
    /// </summary>
    public class UnitDerivation : UnitAbstract
    {
       
        #region 构造函数
        public UnitDerivation()
        {
            list_units = new List<UnitAbstract>();
            localizations = new List<LocalizationClass>();
        }

        public UnitDerivation(string unit_id)
        {
            id = unit_id;
            list_units = new List<UnitAbstract>();
            localizations = new List<LocalizationClass>();
        }

        public UnitDerivation(string unit_id, DimensionClass unit_dimension)
        {
            id = unit_id;
            dimension = unit_dimension;
            list_units = new List<UnitAbstract>();
            localizations = new List<LocalizationClass>();
        }


        #endregion
      
        private string id;
        public new  string ID
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }

        private DimensionClass dimension;
        public new DimensionClass Dimension
        {
            get
            {
                return dimension;
            }
            set
            {
                dimension = value;
            }
        }

        private List<LocalizationClass> localizations;
        public new  List<LocalizationClass> Localizations
        {
            get { return localizations; }
        }
       
        public override void Add_Localization(LocalizationClass item)
        {
            localizations.Add(item);
        }

        public override bool Remove_Localization(LocalizationClass item)
        {
            foreach(LocalizationClass temp in localizations)
            {
                if (temp == item) return localizations.Remove(temp);
            }
            return false;
        }

        public override bool Remove_Localization(LocalizationEnum local)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp.Local == local) return localizations.Remove(temp);
            }
            return false;
        }

        public override LocalizationClass Return_Localization(LocalizationEnum local)
        {
            foreach (LocalizationClass temp in localizations)
            {
                if (temp.Local == local) return temp;
            }
            return null;
        }

        /// <summary>
        /// 复合单位的公式表达式
        /// </summary>
        private string expression;
        public string Expression
        {
            get { return expression; }
            set { expression = value; }
        }

        /// <summary>
        /// 复合单位中包含的简单单位列表
        /// </summary>
        private List<UnitAbstract> list_units;
        public List<UnitAbstract> List_units
        {
            get { return list_units; }
        }

        /// <summary>
        /// 添加基本单位
        /// </summary>
        /// <param name="unit"></param>
        public void Add_Units(UnitAbstract unit)
        {
            list_units.Add(unit);
        }

        #region 移除基本单位

        public void Remove_Units(UnitAbstract unit)
        {
            list_units.Remove(unit);
        }

        public void Remove_Units(string unit_Attribute)
        {
            foreach (UnitAbstract temp in list_units)
            {
                if (temp.ID == unit_Attribute ) list_units.Remove(temp);
            }
        }


        #endregion

        public UnitAbstract Return_Unit(string unit_id)
        {
            try
            {
                foreach(UnitAbstract unit_item in list_units)
                {
                    if(unit_item.ID==unit_id)return unit_item;
                }
                return null;
            }
            catch(Exception ex)
            {
                return null;
            }
        }
      

     

    }

    public class UnitSerialization
    {
        public static string Serialization(UnitAbstract unit)
        {
            string xmlStr = "";
            StringBuilder sb = new StringBuilder();
            XmlWriterSettings xws = new XmlWriterSettings();
            xws.OmitXmlDeclaration = true;
            xws.Indent = true;

            XmlWriter writer = XmlWriter.Create(sb, xws);
            //开始文档
            #region
            writer.WriteStartDocument();
            //开始Dimension
            #region
            writer.WriteStartElement("Unit");
            writer.WriteAttributeString("ID", unit.ID);
            writer.WriteAttributeString("Dimension", unit.Dimension.ID);

            switch (unit.UType)
            {
                case UnitType.basic:
                    writer.WriteAttributeString("Type", "Basic");
                    break;
                case UnitType.primtive:
                    writer.WriteAttributeString("Type", "Primitive");
                    break;
                case UnitType.dervation:
                    writer.WriteAttributeString("Type", "Derivation");
                    break;
            }

            if (unit.UType == UnitType.dervation)
            {
                writer.WriteAttributeString("Expression", ((UnitDerivation)unit).Expression );
            }
            if (unit.UType == UnitType.primtive)
            {
                writer.WriteAttributeString("Expression", ((UnitPrimtive)unit).Expression);
            }

            //本地化开始
            #region
            writer.WriteStartElement("Localizations");
            foreach (LocalizationClass local in unit.Localizations)
            {
                writer.WriteStartElement("Localization");
                if (local.Local == LocalizationEnum.EN_US)
                    writer.WriteAttributeString("Local", "EN_US");
                else if (local.Local == LocalizationEnum.ZH_CN)
                    writer.WriteAttributeString("Local", "ZH_CN");
                writer.WriteAttributeString("Name", local.Name);
                writer.WriteAttributeString("Description", local.Description);
                writer.WriteAttributeString("Symbol", local.Symbol);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
            #endregion
            //本地化结束

            writer.WriteEndElement();
            #endregion
            //结束Dimension
            writer.WriteEndDocument();
            #endregion
            //结束文档
            writer.Flush();

            xmlStr = sb.ToString();
            return xmlStr;
        }

        public static UnitAbstract DeSerialization(string xmlStr)
        {
            UnitAbstract unit = null;
            Stream s = new MemoryStream();
            XmlReader reader = XmlReader.Create(new StringReader(xmlStr));

            reader.ReadToFollowing("Unit");
            string unit_name = reader.GetAttribute("ID");
            string unit_type = reader.GetAttribute("Type");
            if (unit_name == null) unit_name = reader.GetAttribute("id");
            if (unit_type == "Basic")
                unit = new UnitBasic();
            else if (unit_type == "Primitive")
                unit = new UnitPrimtive();
            else if (unit_type == "Derivation")
                unit = new UnitDerivation();

            reader.ReadToFollowing("Localizations");

            #region 读取Localization的属性
            if (reader.ReadToDescendant("Localization"))
            {
                if (reader.GetAttribute("Local") == "EN_US")
                {
                    string name_en = reader.GetAttribute("Name");
                    string symbol_en = reader.GetAttribute("Symbol");
                    string desc_en = reader.GetAttribute("Description");
                    unit.Localizations.Add(new LocalizationClass(LocalizationEnum.EN_US)
                    {
                        Description = desc_en,
                        Name = name_en,
                        Symbol = symbol_en
                    });
                }
                else
                {
                    string name_zh = reader.GetAttribute("Name");
                    string symbol_zh = reader.GetAttribute("Symbol");
                    string desc_zh = reader.GetAttribute("Description");
                    unit.Localizations.Add(new LocalizationClass(LocalizationEnum.ZH_CN)
                    {
                        Description = desc_zh,
                        Name = name_zh,
                        Symbol = symbol_zh
                    });
                }
            }

            if (reader.ReadToNextSibling("Localization"))
            {
                if (reader.GetAttribute("Local") == "EN_US")
                {
                    string name_en = reader.GetAttribute("Name");
                    string symbol_en = reader.GetAttribute("Symbol");
                    string desc_en = reader.GetAttribute("Description");
                    unit.Localizations.Add(new LocalizationClass(LocalizationEnum.EN_US)
                    {
                        Description = desc_en,
                        Name = name_en,
                        Symbol = symbol_en
                    });
                }
                else
                {
                    string name_zh = reader.GetAttribute("Name");
                    string symbol_zh = reader.GetAttribute("Symbol");
                    string desc_zh = reader.GetAttribute("Description");
                    unit.Localizations.Add(new LocalizationClass(LocalizationEnum.ZH_CN)
                    {
                        Description = desc_zh,
                        Name = name_zh,
                        Symbol = symbol_zh
                    });
                }
            }
            #endregion
            reader.Close();

            return unit;
        }
    }
}
